package com.medvalley.tcm.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.medvalley.tcm.base.BusinessException;
import com.medvalley.tcm.dao.Music2CatetoryDao;
import com.medvalley.tcm.dao.MusicCategoryDao;
import com.medvalley.tcm.dao.MusicDao;
import com.medvalley.tcm.dao.MyRecommendMusicDao;
import com.medvalley.tcm.domain.Music;
import com.medvalley.tcm.domain.Music2Category;
import com.medvalley.tcm.domain.MusicCategory;
import com.medvalley.tcm.domain.MyRecommendMusic;
import com.medvalley.tcm.vo.outputvo.MusicCategoryOutputVo;
import com.medvalley.tcm.vo.outputvo.MusicOutputVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import springfox.documentation.spring.web.json.Json;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MusicService {

    @Autowired
    private Music2CatetoryDao music2CatetoryDao;

    @Autowired
    private MusicDao musicDao;

    @Autowired
    private MusicCategoryDao musicCategoryDao;

    @Autowired
    private MyRecommendMusicDao myRecommendMusicDao;

    /**
     * 根据父分类查询分类列表
     *
     * @param parentCateId
     * @return
     */
    public List<MusicCategoryOutputVo> listMusicCategory(int parentCateId) {
        Iterable<MusicCategory> allMusicCates = musicCategoryDao.findAll();
        List<MusicCategory> allCate = Lists.newArrayList(allMusicCates);
        List<MusicCategoryOutputVo> musicCategoryOutputVoList = Lists.newArrayList();
        this.generateOutputVo(musicCategoryOutputVoList, allCate, 0);
        return musicCategoryOutputVoList;
    }

    private void generateOutputVo(List<MusicCategoryOutputVo> musicCategoryOutputVoList, List<MusicCategory> categories, int parentId) {
        List<MusicCategory> subCateList = categories.stream().filter(c -> c.getParentId() == parentId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(subCateList)) {
            return;
        }
        for (int i = 0; i < subCateList.size(); i++) {
            MusicCategoryOutputVo musicCategoryOutputVo = new MusicCategoryOutputVo();
            MusicCategory m = subCateList.get(i);
            BeanUtils.copyProperties(m, musicCategoryOutputVo);
            List<MusicCategoryOutputVo> subOutputList = Lists.newArrayList();
            this.generateOutputVo(subOutputList, categories, m.getId());
            musicCategoryOutputVo.setSubList(subOutputList);
            musicCategoryOutputVoList.add(musicCategoryOutputVo);
        }
    }

    public List<MusicOutputVo> listMusicByCategory(int categoryId) {
        MusicCategory musicCategory = musicCategoryDao.findById(categoryId).orElseThrow(() -> new BusinessException("音乐分类有误"));
        String cateName = musicCategory.getCateName();
        List<MusicOutputVo> musicOutputVoList = Lists.newArrayList();
        List<Music2Category> music2CategoryList = music2CatetoryDao.findAllByCategoryId(categoryId);
        if (!CollectionUtils.isEmpty(music2CategoryList)) {
            List<Integer> musicIds = music2CategoryList.stream().map(Music2Category::getMusicId).collect(Collectors.toList());
            List<Music> musicList = musicDao.findAllByIdIn(musicIds);
            if (!CollectionUtils.isEmpty(musicList)) {
                musicList.forEach(m -> {
                    MusicOutputVo musicOutputVo = new MusicOutputVo();
                    musicOutputVo.setCateId(categoryId);
                    musicOutputVo.setCateName(cateName);
                    BeanUtils.copyProperties(m, musicOutputVo);
                    musicOutputVoList.add(musicOutputVo);
                });
            }
        }
        return musicOutputVoList;
    }

    /**
     * @param userId
     * @param questionType   问卷类型
     * @param questionResult 问卷结果
     */
    public void recommendMusic(long userId, int questionType, String questionResult) {

        List<MusicCategory> musicCategory = musicCategoryDao.findByQuestionTypeNameIsLike(questionResult + "%");
        if (CollectionUtils.isEmpty(musicCategory)) {
            log.warn("recommendMusic musicCategory is empty,userId:{},quetionType:{},questionResult:{}", userId, questionType, questionResult);
            return;
        }
        int cateId = musicCategory.get(0).getId();
        log.info("recommendMusic userId:{},questionType:{},questionResult:{} cateId:{} ", userId, questionType, questionResult, cateId);
        String catName = musicCategory.get(0).getCateName();
        List<Music2Category> music2CategoryList = music2CatetoryDao.findByRand(10, cateId);
        if (CollectionUtils.isEmpty(music2CategoryList)) {
            log.warn("recommendMusic music is empty,userId:{},quetionType:{},questionResult:{},cateId:{}", userId, questionType, questionResult, cateId);
            return;
        }
        List<Integer> mIds = music2CategoryList.stream().map((e) -> e.getMusicId()).collect(Collectors.toList());
        log.info("recommendMusic userId:{},questionType:{},questionResult:{} cateId:{} mIds:{} ", userId, questionType, questionResult, cateId, mIds);
        List<Music> recommendMusic = musicDao.findAllByIdIn(mIds);
        log.info("recommendMusic userId:{},questionType:{},questionResult:{} cateId:{} find music_count:{} ", userId, questionType, questionResult, cateId, recommendMusic.size());
        List<MyRecommendMusic> recommendMusicList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(recommendMusic)) {
            myRecommendMusicDao.deleteByUserIdAndCheckType(userId, questionType);
            recommendMusic.forEach(rm -> {
                MyRecommendMusic myRecommendMusic = new MyRecommendMusic();
                myRecommendMusic.setUserId(userId);
                myRecommendMusic.setMusicId(rm.getId());
                myRecommendMusic.setCatId(cateId);
                myRecommendMusic.setCatName(catName);
                myRecommendMusic.setCheckType(questionType);
                myRecommendMusic.setMusicName(rm.getMusicName());
                myRecommendMusic.setMusician(rm.getMusician());
                myRecommendMusic.setMusicDuration(rm.getMusicDuration());
                myRecommendMusic.setMusicUrl(rm.getMusicUrl());
                myRecommendMusic.setCreateTime(new Date());
                recommendMusicList.add(myRecommendMusic);
                log.info("recommendMusic userId:{},questionType:{},questionResult:{} cateId:{} save :{} ", userId, questionType, questionResult, cateId, JSON.toJSONString(myRecommendMusic));

            });
        }
        myRecommendMusicDao.saveAll(recommendMusicList);
    }
}
